//#define _CRTDBG_MAP_ALLOC
//
//#include <stdlib.h>
//
//#include <crtdbg.h>

#include <stdio.h>
#include <string.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <assert.h>

#include "token.h"
#include "ast.h"
#include "base.h"
#include "option.h"
#include "expr.h"
#include "stmt.h"
#include "buffer.h"
#include "module.h"

//on_ff = true: print memory leak
#ifdef WIN32
void detect_memory_leaks(bool on_off)
{
    _CrtSetBreakAlloc(-1);
    int flags = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
    if (!on_off)
        flags &= ~_CRTDBG_LEAK_CHECK_DF;
    else {
        flags |= _CRTDBG_LEAK_CHECK_DF;
        flags |= _CRTDBG_ALLOC_MEM_DF;
        flags |= _CRTDBG_MODE_DEBUG;
        //_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
        //_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
    }
    _CrtSetDbgFlag(flags);
}
#else
void detect_memory_leaks(bool on_off)
{
    (void)on_off;
}
#endif

int main(int argc, char *argv[])
{
    //detect_memory_leaks(true);

    parse_option(argc, argv);

    char* filename = g_option.filename;
    buffer_t* buf = NULL;

    if (g_option.token_only) {
        printf("parsing token of %s\n", filename ? filename : "stdout");
        buf = read_to_buffer(filename);
        if (!buf) {
            fprintf(stderr, "error: can't read the input file: %s\n", filename);
            return -1;
        }
        init_token(buf->data, buf->size, filename);
        token_t token;
        int i = 0;
        do {
            token = get_token();
            if (g_option.dump_token) {
                print_token(&token);
            }
            i++;
        } while (token.kind != TK_NONE);
        printf("------------------------------------\n");
        int ret = -token_error_count();
        finish_token();
        return ret;
    }

    if (filename != NULL) {
        ast_t* ast = new ast_t;
        if (ast == nullptr) {
            return -1;
        }
        auto ret = import_file(ast, filename);
        delete ast;
        free_all_ref();
        free_globals();
        finish_token();
        return ret;
    }

    while (1) {
        printf("input: ");
        buf = stdin_line_to_buffer();
        if (buf != NULL && buf->size > 0 && buf->data[0] == EOF) {
            break;
        }
        if (buf && buf->size > 0) {
            ast_t ast;
            import_buffer(&ast, buf);
            ast.buf = nullptr;
        }
        free_buffer(buf);
    }

    return 0;
}